package com.cpr.rwqd_sjjn.controller;

import com.cpr.rwqd_sjjn.entity.User;
import com.cpr.rwqd_sjjn.request.ChangePasswordRequest;
import com.cpr.rwqd_sjjn.request.RegisterRequest;
import com.cpr.rwqd_sjjn.service.UserService;
import com.cpr.rwqd_sjjn.util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/hzd")
@Tag(name="用户管理接口")
@Validated // 启用Spring的验证支持
public class UserController {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private JwtUtil jwtUtil;

    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> handleException(Exception ex) {
        log.error("发生未知错误: ", ex);
        return new ResponseEntity<>(new ResponseMessage("服务器内部错误"), HttpStatus.INTERNAL_SERVER_ERROR);
    }


    // 新增：获取验证码的接口
    @PostMapping("/sendVerificationCode")
    @Operation(summary="发送验证码")
    public ResponseEntity<?> sendVerificationCode(@RequestBody Map<String, String> request) {
        String email = request.get("email");
        if (email == null || email.trim().isEmpty()) {
            return new ResponseEntity<>(new ResponseMessage("无效的邮箱地址"), HttpStatus.BAD_REQUEST);
        }

        userService.sendVerificationCode(email);
        return new ResponseEntity<>(new ResponseMessage("验证码已发送，请查收邮件并验证"), HttpStatus.OK);
    }

    @PostMapping("/register")
    @Operation(summary = "注册")
    public ResponseEntity<?> register(@RequestBody RegisterRequest registerRequest) {
        // 获取请求参数
        User user = registerRequest.getUser();
        String emailVerificationCode = registerRequest.getEmailVerificationCode();

        // 验证输入数据是否为空
        if (user == null ||
                user.getNumber() == null ||
                user.getEmail() == null ||
                user.getPassword() == null ||
                user.getName() == null ||
                emailVerificationCode == null ||
                emailVerificationCode.trim().isEmpty()) {
            return new ResponseEntity<>(new ResponseMessage("无效的请求参数"), HttpStatus.BAD_REQUEST);
        }

        // 调用服务层进行注册，并传递验证码
        String result = userService.register(registerRequest);

        // 根据服务层返回的结果设置相应的HTTP响应
        switch (result) {
            case "密码格式不符合要求：8-20位，至少包含大写字母、小写字母、数字中的两种，且不能包含中文字符":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.BAD_REQUEST); // 密码格式错误
            case "该号码已注册":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.CONFLICT); // 号码已注册
            case "该邮箱已被其他用户绑定":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.CONFLICT); // 邮箱冲突
            case "验证码错误或已失效，请重新获取验证码":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.UNAUTHORIZED); // 验证码错误或过期
            case "注册成功":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.CREATED); // 注册成功
            default:
                return new ResponseEntity<>(new ResponseMessage("服务器内部错误"), HttpStatus.INTERNAL_SERVER_ERROR); // 其他错误情况
        }
    }

    @PostMapping("/change-password")
    @Operation(summary = "修改密码")
    public ResponseEntity<?> changePassword(
            @RequestHeader(value = "Authorization", required = false) String authorizationHeader,
            @RequestBody @Valid ChangePasswordRequest changePasswordRequest) {

        // 检查 Authorization Header 是否存在
        if (authorizationHeader == null) {
            return new ResponseEntity<>(new ResponseMessage("缺少 Authorization Header，请先登录"), HttpStatus.UNAUTHORIZED);
        }
        if (!authorizationHeader.startsWith("Bearer ")) {
            return new ResponseEntity<>(new ResponseMessage("Authorization Header 格式错误，应为 'Bearer <Token>'"), HttpStatus.UNAUTHORIZED);
        }

        // 提取 Token
        String rawToken = authorizationHeader.substring(7); // 去掉 "Bearer " 前缀

        // 验证 Token 是否有效
        try {
            Claims claims = jwtUtil.extractClaims(rawToken); // 解析 Token 并提取 Claims
            log.info("Extracted Token: {}", rawToken);
            if (jwtUtil.isTokenExpired(claims)) { // 检查 Token 是否过期
                return new ResponseEntity<>(new ResponseMessage("Token 已过期，请重新登录"), HttpStatus.UNAUTHORIZED);
            }
        } catch (Exception e) {
            log.warn("Token 验证失败: {}", e.getMessage());
            return new ResponseEntity<>(new ResponseMessage("Token 解析失败，请重新登录"), HttpStatus.UNAUTHORIZED);
        }

        // 从封装对象中获取参数
        String email = changePasswordRequest.getEmail();
        String newPassword = changePasswordRequest.getNewPassword();
        String emailVerificationCode = changePasswordRequest.getEmailVerificationCode();

        // 验证输入数据是否为空
        if (email == null || newPassword == null || emailVerificationCode == null ||
                email.trim().isEmpty() || newPassword.trim().isEmpty() ||
                emailVerificationCode.trim().isEmpty()) {
            return new ResponseEntity<>(new ResponseMessage("无效的请求参数"), HttpStatus.BAD_REQUEST);
        }

        // 调用服务层进行密码修改
        String result = userService.changePassword(email, newPassword, emailVerificationCode);

        // 根据服务层返回的结果设置相应的 HTTP 响应
        switch (result) {
            case "密码格式不符合要求：8-20位，至少包含大写字母、小写字母、数字中的两种，且不能包含中文字符":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.BAD_REQUEST); // 密码格式错误
            case "未找到与该邮箱关联的用户":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.NOT_FOUND); // 用户不存在
            case "验证码错误或已失效，请重新获取验证码":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.UNAUTHORIZED); // 验证码错误或过期
            case "密码修改成功":
                return new ResponseEntity<>(new ResponseMessage(result), HttpStatus.OK); // 修改成功
            default:
                return new ResponseEntity<>(new ResponseMessage("服务器内部错误"), HttpStatus.INTERNAL_SERVER_ERROR); // 其他错误情况
        }
    }

    @PostMapping("/login-by-number-password")
    @Operation(summary = "账号密码登录")
    public ResponseEntity<?> loginByNumberAndPassword(@RequestBody Map<String, String> loginRequest) {
        String number = loginRequest.get("number");
        String password = loginRequest.get("password");

        // 验证参数是否为空
        if (number == null || password == null) {
            return new ResponseEntity<>(new ResponseMessage("缺少必要参数"), HttpStatus.BAD_REQUEST);
        }

        try {
            // 调用服务层进行登录验证
            Map<String, Object> userInfo = userService.loginByNumberAndPassword(number, password);

            // 登录成功，生成 Token
            String token = jwtUtil.generateToken(number);
            log.info("生成的 Token: {}", token); // 打印生成的 Token

            // 构建响应数据
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("token", token);
            responseData.put("userId", userInfo.get("userId"));
            responseData.put("name", userInfo.get("name"));
            responseData.put("roles", userInfo.get("roles"));

            // 返回成功响应
            return new ResponseEntity<>(new ResponseMessage("登录成功", responseData), HttpStatus.OK);
        } catch (RuntimeException e) {
            // 捕获自定义异常并返回相应的错误信息
            String errorMessage = e.getMessage();
            if ("该号码未注册".equals(errorMessage)) {
                return new ResponseEntity<>(new ResponseMessage(errorMessage), HttpStatus.NOT_FOUND);
            } else if ("密码错误，可尝试邮箱登录".equals(errorMessage)) {
                return new ResponseEntity<>(new ResponseMessage(errorMessage), HttpStatus.UNAUTHORIZED);
            } else {
                return new ResponseEntity<>(new ResponseMessage("服务器内部错误"), HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    }

    @PostMapping("/login-by-email-code")
    @Operation(summary = "邮箱验证码登录")
    public ResponseEntity<?> loginByEmailAndCode(@RequestBody Map<String, String> request) {
        String email = request.get("email");
        String code = request.get("code");

        // 验证参数是否为空
        if (email == null || email.trim().isEmpty()) {
            return new ResponseEntity<>(new ResponseMessage("邮箱不能为空"), HttpStatus.BAD_REQUEST);
        }

        try {
            // 调用服务层进行邮箱验证码登录验证
            Map<String, Object> result = userService.loginByEmailAndCode(email, code);

            // 根据返回的状态设置 HTTP 响应
            String status = (String) result.get("status");
            if ("success".equals(status)) {
                // 登录成功，生成 Token
                String token = jwtUtil.generateToken(email);
                log.info("生成的 Token: {}", token);
                result.put("token", token);

                // 构建统一的响应数据
                Map<String, Object> responseData = new HashMap<>();
                responseData.put("token", result.get("token"));
                responseData.put("userId", result.get("userId"));
                responseData.put("name", result.get("name"));
                responseData.put("roles", result.get("roles"));

                return new ResponseEntity<>(new ResponseMessage("登录成功", responseData), HttpStatus.OK);
            } else if ("info".equals(status)) {
                // 验证码已发送
                return new ResponseEntity<>(new ResponseMessage((String) result.get("message")), HttpStatus.ACCEPTED);
            } else {
                // 登录失败
                return new ResponseEntity<>(new ResponseMessage((String) result.get("message")), HttpStatus.UNAUTHORIZED);
            }
        } catch (RuntimeException e) {
            // 捕获异常并返回服务器内部错误
            return new ResponseEntity<>(new ResponseMessage("服务器内部错误"), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @Data // 自动生成 getter 和 setter 方法，以及 toString、equals 和 hashCode 方法
    @NoArgsConstructor // 自动生成无参构造函数
    public class ResponseMessage {
        private String message; // 响应消息
        private Object data;   // 通用数据字段，支持多种类型（如 String、Map 等）

        // 构造函数1：只传递 message
        public ResponseMessage(String message) {
            this.message = message;
            this.data = null; // 默认 data 为 null
        }

        // 构造函数2：同时传递 message 和 token
        public ResponseMessage(String message, String token) {
            this.message = message;
            this.data = token; // 将 token 存储到 data 中
        }

        // 构造函数3：同时传递 message 和复杂数据（如 Map）
        public ResponseMessage(String message, Object data) {
            this.message = message;
            this.data = data;
        }
    }
}